package cs2114.antiFingerMines;

import java.util.Random;

/**
 * // -------------------------------------------------------------------------
 * /** Holds the array with all of the mines.
 *
 * @author Blake Whaley
 * @version Apr 10, 2012
 */
public class MineField
    extends AntiFingerMineAbstract
{

    /**
     * Constructor.
     */
    public MineField(float w, float h, int mines)
    {
        newGame(w, h, mines);
    }

    public float distanceToClosestMine()
    {
        float closest = 99999;
        for (int i = 0; i < field.length; i++)
        {
            if (field[i].traversableDistanceBetween(finger) <= closest)
            {
                closest = field[i].traversableDistanceBetween(finger);
            }
        }
        setChanged();
        notifyObservers();
        return closest;
    }

    /**
     * Randomly places mines in the array.
     */
    public void placeMines()
    {
        Random rand = new Random();
        int i = 0;
        while (numMines > 0)
        {
            int wmine = rand.nextInt((int)viewWidth);
            int hmine = rand.nextInt((int)viewHeight);
            int rlimit = rand.nextInt(60) + 20;
            Mine newMine = new Mine(wmine, hmine, rlimit);
            for (int j = 0; j < field.length - numMines; j++)
            {
                double between = field[j].traversableDistanceBetween(newMine);
                double center =
                    newMine.traversableDistanceBetween(getFingerLocation());
                if (between < 40 || center <= 0)
                {
                    wmine = rand.nextInt((int)viewWidth);
                    hmine = rand.nextInt((int)viewHeight);
                    rlimit = rand.nextInt(60) + 20;
                    newMine = new Mine(wmine, hmine, rlimit);
                    j = -1;
                }
            }
            field[i] = newMine;
            i++;
            numMines--;
        }
    }


    public float getWidth()
    {
        return viewWidth;
    }


    public float getHeight()
    {
        return viewHeight;
    }


    public int size()
    {
        return field.length;
    }


    public Mine getMine(int index)
    {
        return field[index];
    }


    @Override
    public Location getFingerLocation()
    {
        return finger;
    }


    @Override
    public void setFingerLocation(float x, float y)
    {
        finger.setXloc(x);
        finger.setYloc(y);
        this.isGameOver();
        setChanged();
        notifyObservers();
    }


    public boolean isGameOver()
    {
        status = false;
        if (this.distanceToClosestMine() <= 0)
        {
            status = true;
        }
        return status;
    }


    @Override
    public void newGame(float w, float h, int mines)
    {
        numMines = mines;
        viewWidth = w;
        viewHeight = h;
        startOfField = viewHeight / 10;
        endOfField = viewHeight - 2 * startOfField;
        field = new Mine[numMines];
        finger = new Location(viewWidth / 2, 25);
        spaceForMine = (endOfField - startOfField) / 2;
        // The reason why the message kept coming up was because you forgot
        // to reset the gamelost status to false, so everytime we the button
        // made a new game it still saw the boolean as true and thought we lost.
        // The button works now.
        status = false;
        this.placeMines();

    }

    /**
     * This method makes a new game with setRandom mines instead of place mines
     * @param w
     * @param h
     * @param mines
     */
    public void newGame1(float w, float h, int mines)
    {
        numMines = mines;
        viewWidth = w;
        viewHeight = h;
        startOfField = viewHeight / 10;
        endOfField = viewHeight - 2 * startOfField;
        field = new Mine[numMines];
        finger = new Location(viewWidth / 2, 25);
        spaceForMine = (endOfField - startOfField) / 2;
        // The reason why the message kept coming up was because you forgot
        // to reset the gamelost status to false, so everytime we the button
        // made a new game it still saw the boolean as true and thought we lost.
        // The button works now.
        status = false;
        this.setRandomMines();

    }

    @Override
    public void setWidth(float w)
    {
        viewWidth = w;

    }


    @Override
    public void setHeight(float h)
    {
        viewHeight = h;

    }


    @Override
    public void setRandomMines()
    {
        Random rand = new Random();

        for (int i = 0; i < numMines; i++)
        {
            field[i] =
                new Mine(
                    rand.nextFloat() * viewWidth,
                    startOfField + i * spaceForMine + rand.nextFloat()
                        * spaceForMine,
                    spaceForMine);
        }

    }


    public boolean hasWon()
    {
        if (finger.getYloc() > endOfField)
        {
            return true;
        }
        return false;
    }


    public float getEndOfField()
    {
        return endOfField;
    }
}
